package cn.sciento.core.endpoint.request;

import java.util.Map;
import cn.sciento.core.endpoint.HttpRequest;
import cn.sciento.core.util.ServiceInstanceUtils;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.util.MultiValueMap;

public class EndpointRequest<T> implements HttpRequest<T> {
  private static final String ACTUATOR_CONTEXT_PATH = "/actuator";
  
  private final HttpHeaders headers = new HttpHeaders();
  
  private ServiceInstance instance;
  
  private EndpointKey endpointKey;
  
  private HttpMethod httpMethod;
  
  private Map<String, String> requestParams;
  
  private HttpEntity<byte[]> httpEntity;
  
  private Class<T> responseClass;
  
  public EndpointRequest(ServiceInstance instance, EndpointKey endpointKey, HttpMethod httpMethod, Map<String, String> requestParams, byte[] requestBody, Class<T> responseClass) {
    this.headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
    this.instance = instance;
    this.endpointKey = endpointKey;
    this.httpMethod = httpMethod;
    this.requestParams = requestParams;
    this.httpEntity = new HttpEntity(requestBody, (MultiValueMap)this.headers);
    this.responseClass = responseClass;
  }
  
  public EndpointRequest(ServiceInstance instance, EndpointKey endpointKey, HttpMethod httpMethod, Class<T> responseClass) {
    this(instance, endpointKey, httpMethod, null, null, responseClass);
  }
  
  public EndpointRequest(ServiceInstance instance, EndpointKey endpointKey, HttpMethod httpMethod, Map<String, String> requestParams, Class<T> responseClass) {
    this(instance, endpointKey, httpMethod, requestParams, null, responseClass);
  }
  
  public EndpointRequest(ServiceInstance instance, EndpointKey endpointKey, HttpMethod httpMethod, byte[] requestBody, Class<T> responseClass) {
    this(instance, endpointKey, httpMethod, null, requestBody, responseClass);
  }
  
  @Override
  public String getSchema() {
    return "http://";
  }
  
  @Override
  public String getUrl() {
    return this.instance.getHost() + ":" + 
      ServiceInstanceUtils.getManagementPortFromMetadata(this.instance) + "/actuator" + 
      
      ServiceInstanceUtils.getValueFromMetadata(this.instance, this.endpointKey.getKey()) + 
      toString(this.requestParams);
  }
  
  @Override
  public HttpMethod getMethod() {
    return this.httpMethod;
  }
  
  @Override
  public HttpEntity<byte[]> getHttpEntity() {
    return this.httpEntity;
  }
  
  @Override
  public Class<T> getResponseClass() {
    return this.responseClass;
  }
}
